import 'dart:convert';
import 'dart:io';

import 'package:ladder_cash/app/com/model/request_default_params_model.dart';
import 'package:ladder_cash/app/com/plugin/device_data_plugin.dart';
import 'package:ladder_cash/app/com/view/common_view.dart';
import 'package:dio/dio.dart';
import 'dart:collection';

import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http_proxy/http_proxy.dart';

import 'package:liuxlcommon/util/print_utils.dart';
import 'package:liuxlcommon/util/string_utils.dart';
import 'package:liuxlcommon/util/toast_util.dart';
import 'package:ladder_cash/app/app.dart';
import 'package:ladder_cash/app/com/http/code.dart';
import 'package:ladder_cash/app/com/http/Res.dart';
import 'package:ladder_cash/app/key_mix.dart';
import 'package:ladder_cash/generated/json/base/json_convert_content.dart';

import '../../../library/src/logger.dart';

//动态域名：https://mx01-dc.oss-us-west-1.aliyuncs.com/ladder-cash/lc.json
//默认接口: https://molo.aaradhya-capital.com/linear/
//官网：https://aaradhya-capital.com/
//隐私协议：https://aaradhya-capital.com/MoloPrivacyPolicy.html     @小岩岩
// https://mx01-dc.oss-us-west-1.aliyuncs.com/ladder-cash/lc.json
// https://lcm.himmat-limited.com/linear/
// https://himmat-limited.com
// https://himmat-limited.com/HIMPrivacy.html

class HttpRequest {
  static String TAG = "HttpRequest";

  // static const String host = "http://47.251.21.214";
  static const String host = "https://lcm.himmat-limited.com";
  static String _baseUrl = "$host/linear";
  static RequestDefaultParamsModel? requestDefaultParamsModel;
  static bool isProxy = true;

  static BaseOptions _options = getDefOptions();

  static Map optionParams = {"timeoutMs": 60000};

  static setBaseUrl(String baseUrl) {
    _baseUrl = baseUrl;
  }

  static String getBaseUrl() {
    return _baseUrl;
  }

  static BaseOptions getDefOptions() {
    BaseOptions options = BaseOptions();
    options.connectTimeout = const Duration(milliseconds: 100 * 1000);
    options.receiveTimeout = const Duration(milliseconds: 200 * 1000);
    // options.contentType = ContentType.parse('application/x-www-form-urlencoded');
    options.baseUrl = _baseUrl;
    Map<String, dynamic> headers = {};
    headers['Accept'] = 'application/x-www-form-urlencoded';
    headers['content-type'] = 'application/x-www-form-urlencoded';
    options.headers = headers;
    return options;
  }

  ///前面不要加 / 斜杠
  /// [url] 网路请求路径
  /// [param] 参数
  /// [context] 需要从页面传过来，跟[loadingText]一起使用，显示加载动画
  /// [loadingText] 加载动画文字
  /// [parse] 默认为true ， 表示return Data的数据
  /// [isnull] 去除null 的参数
  get<T>(url, param,
      {context,
      loadingText,
      parse = true,
      Options? options,
      isnull,
      autoToast}) async {
    return await post<T>(url, param,
        context: context,
        loadingText: loadingText,
        parse: parse,
        options: Options(method: "GET"),
        isnull: isnull,
        autoToast: autoToast);
  }

  getList<T>(url, param,
      {context, loadingText, parse = true, Options? options, isnull}) async {
    return await post<T>(url, param,
        context: context,
        loadingText: loadingText,
        parse: parse,
        options: Options(method: "GET"),
        isList: true,
        isnull: isnull);
  }

  putList<T>(url, param,
      {context, loadingText, parse = true, Options? options, isnull}) async {
    return await post<T>(url, param,
        context: context,
        loadingText: loadingText,
        parse: parse,
        options: Options(method: "PUT"),
        isList: true,
        isnull: isnull);
  }

  putRes(url, param,
      {context, loadingText, parse = false, Options? options, isnull}) async {
    return await post(url, param,
        context: context,
        loadingText: loadingText,
        parse: parse,
        options: Options(method: "PUT"),
        isnull: isnull);
  }

  put<T>(url, param,
      {context, loadingText, parse = true, Options? options, isnull}) async {
    return await post<T>(url, param,
        context: context,
        loadingText: loadingText,
        parse: parse,
        options: Options(method: "PUT"),
        isnull: isnull);
  }

  ///前面不要加 / 斜杠
  /// [url] 网路请求路径
  /// [param] 参数
  /// [context] 需要从页面传过来，跟[loadingText]一起使用，显示加载动画
  /// [loadingText] 加载动画文字
  /// [parse] 默认为true ， 表示return Data的数据
  /// [isnull] 去除null 的参数
  Future postList<T>(url, param,
      {context, loadingText, parse = true, Options? options, isnull}) async {
    return await post<T>(url, param,
        context: context,
        loadingText: loadingText,
        parse: parse,
        isList: true,
        options: Options(method: "POST"),
        isnull: isnull);
  }

  Future postRes<T>(url, param,
      {context, loadingText, parse = true, Options? options, isnull, isList}) {
    return post(url, param,
        context: context,
        parse: false,
        options: options,
        isnull: isnull,
        isList: isList,
        loadingText: loadingText);
  }

  ///可以关闭
  static bool isDis = true;

  ///前面不要加 / 斜杠
  /// [url] 网路请求路径
  /// [param] 参数
  /// [context] 需要从页面传过来，跟[loadingText]一起使用，显示加载动画
  /// [loadingText] 加载动画文字
  /// [parse] 默认为true ， 表示return Data的数据
  /// [isnull] 去除null 的参数
  Future post<T>(url, param,
      {context,
      loadingText,
      parse = true,
      Options? options,
      isnull,
      isList,
      isPrintLog = true,
      autoToast = true}) async {
    if (isnull == true) {
      var p = {};
      (param as Map).forEach((key, value) {
        if (value != null) p[key] = value;
      });
      param = p;
    }

    if (loadingText != null) {
      if (EasyLoading.isShow) {
        isDis = false;
      } else {
        EasyLoading.show(status: loadingText);
      }
    }
    String json = JsonEncoder().convert(param);

    if (isPrintLog) {
      PrintUtils.print1(TAG + 'token', App.token);
      PrintUtils.print1(TAG + 'url', url);
      PrintUtils.print1(TAG + 'param', json);
    }

    Res a = await request(url, param, {"token": App.token ?? ""},
        options ?? Options(method: "POST"),
        isPrintLog: isPrintLog);
    if (loadingText != null) {
      isDis = true;
      Future.delayed(const Duration(milliseconds: 30)).then((value) {
        if (isDis) {
          EasyLoading.dismiss();
        }
      });
    }
    if (!a.isSuccess() && autoToast == true) {
      ToastUtils.showToast(msg: a.msg);
    }
    if (parse) {
      if (a.data == null) return null;
      if (!a.success) return null;
      if (null is T) return a.data;
      if (isList ?? false) {
        if (a.data != null && a.data is List) {
          return JsonConvert().convertListNotNull<T>(a.data);
        } else if (a.data != null && a.data['list'] != null) {
          return JsonConvert().convertListNotNull<T>(a.data['list']);
        } else
          return <T>[];
      }
      return JsonConvert.fromJsonAsT<T>(a.data) ?? a.data;
    }
    return a;
  }

  postfile(path, Map<String, dynamic>? map,
      {context, loadingText, parse = true, Options? options}) async {
    map ??= <String, dynamic>{};
    String name = path.substring(path.lastIndexOf('/') + 1);
    PrintUtils.print1("postfile", json.encode(map));
    map["usesMaegyr"] = await MultipartFile.fromFile(path, filename: name);
    FormData formData = FormData.fromMap(map);
    if (loadingText != null) EasyLoading.show(status: loadingText);
    Res a = await request('/credit-info/upload-image'.hx, formData,
        {"token": App.token ?? ""}, options ?? Options(method: "POST"));
    if (loadingText != null) EasyLoading.dismiss();
    if (parse) {
      if (a.data == null) Fluttertoast.showToast(msg: a.msg);
      return a.data;
    }
    return a;
  }

  static delete(url, param) async {
    return await request(url, param, null, Options(method: 'DELETE'));
  }

  ///发起网络请求
  ///[ url] 请求url
  ///[ params] 请求参数
  ///[ header] 外加头
  ///[ option] 配置
  static request(
      String url, params, Map<String, String>? header, Options option,
      {noTip = false, isPrintLog = true}) async {
    String lUrl = url;
    if (!url.contains("http")) {
      // if (isProxy) {
      //   _baseUrl = "http://149.129.247.212:8967/kredit";
      // } else {
      //   _baseUrl = "$host/kredit";
      // }
      url = _baseUrl + url;
    }
    if (StringUtils.isEmpty(requestDefaultParamsModel?.adid)) {
      requestDefaultParamsModel =
          await DeviceDataPlugin.getRequestDefaultParams;
    }
    url = '$url?${'appVersion'.hx}=${requestDefaultParamsModel!.appVersion}';
    url = '$url&${'deviceName'.hx}=${requestDefaultParamsModel!.deviceName}';
    url = '$url&${'deviceId'.hx}=${requestDefaultParamsModel!.deviceId}';
    url =
        '$url&${'osVersion'.hx}=${requestDefaultParamsModel!.deviceOsVersion}';
    url = '$url&${'sessionId'.hx}=${App.token}';
    url = '$url&${'gps_adid'.hx}=${requestDefaultParamsModel!.adid}';
    url = '$url&${'isNeedPop'.hx}=${App.localeCode == "en" ? 1 : 2}';
    //没有网络
    // var connectivityResult = await (  Connectivity().checkConnectivity());
    // if (connectivityResult == ConnectivityResult.none) {
    //   return new Abs(Code.NETWORK_ERROR, Code.CodeStrs[Code.NETWORK_ERROR], null);
    // }

    Map<String, String> headers = HashMap();
    if (header != null) {
      headers.addAll(header);
    }

    // 设置 baseUrl

    if (option != null) {
      option.headers = headers;
    } else {
      option = Options(method: "get");
      option.headers = headers;
    }

    ///超时
    Dio dio = Dio(_options);
    if (!await checkInternetConnection()) {}

    ///启用代理不抓包
    if (isProxy) {
      HttpProxy httpProxy = await HttpProxy.createHttpProxy();
      HttpOverrides.global = httpProxy;
    }

    Response response;
    try {
      PrintUtils.print1(TAG + 'url', url);
      if (isPrintLog) {
        PrintUtils.print1(TAG + 'token', App.token);
        PrintUtils.print1(TAG + 'param', params);
        PrintUtils.print1(TAG + 'header', dio.options.headers);
      }

      if (option.method!.contains("GET")) {
        response = await dio.request(
          url,
          queryParameters: params,
          options: option,
        );
      } else {
        var data = (params is FormData) ? params : FormData.fromMap(params);
        response = await dio.request(
          url,
          data: data,
          options: option,
        );
      }
    } on DioError catch (e) {
      // 请求错误处理
      Response errorResponse;
      if (e.response != null) {
        errorResponse = e.response ??
            Response(statusCode: 666, requestOptions: RequestOptions(path: ""));
      } else {
        errorResponse = Response(
            statusCode: 666,
            statusMessage: e.message ?? "Network Error",
            requestOptions: RequestOptions(path: ""));
      }
      // if (e.type == DioErrorType.connectTimeout) {
      //   errorResponse.statusCode = Code.NETWORK_TIMEOUT;
      // }
      errorResponse.statusMessage ??= "";
      PrintUtils.print1('$TAG 请求异常 ',
          "code:${errorResponse.statusCode!}  message：${errorResponse.statusMessage!}");
      PrintUtils.print1('$TAG 请求异常 url ', url);
      if (errorResponse.data != null) {
        PrintUtils.print1(TAG + ' 请求异常 data ', errorResponse.data.toString());
      }
      DeviceDataPlugin.sendBroadcastNetwork(
          url, json.encode(params), errorResponse.data);

      if (errorResponse.data != null && errorResponse.data.length != 0) {
        if (errorResponse.data is String) {
          return Res(errorResponse.statusCode!, errorResponse.data, null);
        }
        return Res(
            errorResponse.statusCode!, errorResponse.data!.toString(), null);
      } else {
        return Res(
            errorResponse.statusCode!, errorResponse.statusMessage!, null);
      }
    }

    try {
      if (response.statusCode == 200 || response.statusCode == 201) {
        try {
          String json1 = json.encode(response.data);
          DeviceDataPlugin.sendBroadcastNetwork(
              url, json.encode(params), json1);
          PrintUtils.print1('${lUrl.rhx}: data', json1);
        } catch (e) {
          PrintUtils.print1('${lUrl.rhx}: data', response.data.toString());
        }

        dynamic s = response.data;
        // s = StringKeyMix.jsonConvertMapHx(s);
        // Abs a=new Abs(s["Code"],s["Msg"] ,s["Data"]);
        int code = int.parse(StringUtils.defaultValue(
            s['code'.hx].toString(), s['code'].toString()));
        Res a = Res(
            code, s['message'.hx] ?? s['message'], s['data'.hx] ?? s['data']);
        if (!a.success) {
          print("sdf");
        }
        if (a.data is String && a.data.toString().contains('\r\n')) {
          dynamic s = json.decode(a.data.toString().replaceAll('\r\n', '\n'));
          a.data = s;
        }
        if (a.code == -2) {
          App.logout();
        }
        return a;
      }
    } catch (e) {
      return Res(
          Code.NETWORK_ERROR, response.statusCode.toString(), response.data);
    }
  }

  Future<bool> setDynamicDomain({url = "$host/linear/"}) async {
    if (!await checkInternetConnection()) {}
    Dio d = Dio();
    try {
      Response response = await d.get(url,
          options: Options(sendTimeout: const Duration(seconds: 5)));
      if (int.tryParse(response.data?['code'.hx]?.toString() ?? "-1") == 0) {
        return true;
      } else {}
    } catch (e) {
    }
    if (url == "$host/linear/") {
      ///请求失败，请求动态域名
      for (dynamic domain in await getDomainList()) {
        String url0 = domain['lc'];
        if (url0 == "$host/linear/") {
          continue;
        }
        if (await setDynamicDomain(url: url0)) {
          _baseUrl = url0;
          return true;
        }
      }
    }
    return false;
  }

  Future<List> getDomainList() async {
    Dio d = Dio();
    try {
      Response response = await d.get(
          "https://mx01-dc.oss-us-west-1.aliyuncs.com/ladder-cash/lc.json",
          options: Options(sendTimeout: const Duration(seconds: 1)));
      List data = response.data;
      List resutl = [...data, ...data, ...data];
      return resutl;
    } catch (e) {}
    return [];
  }

  // Future<bool> setDynamicDomainAndroid(
  //     {url = "https://dinero-rapido.nakodarfin-in.com/anglars/"}) async {
  //   if (!await checkInternetConnection()) {}
  //   Dio d = Dio();
  //   try {
  //     Response response = await d.get(url,
  //         options: Options(sendTimeout: const Duration(seconds: 5)));
  //     if (int.tryParse(response.data?["code"]?.toString() ?? "-1") == 0) {
  //       return true;
  //     }
  //   } catch (e) {}
  //   if (url == "https://dinero-rapido.nakodarfin-in.com/anglars/") {
  //     ///请求失败，请求动态域名
  //     for (dynamic domain in await getDomainListAndroid()) {
  //       String url0 = domain['di'];
  //       if (url0 == "https://dinero-rapido.nakodarfin-in.com/anglars/") {
  //         continue;
  //       }
  //       bool b = await setDynamicDomainAndroid(url: url0);
  //       if (b) {
  //         _baseUrl = url0;
  //         return true;
  //       }
  //     }
  //   }
  //   return false;
  // }

  Future<List> getDomainListAndroid() async {
    Dio d = Dio();
    try {
      Response response = await d.get(
          "https://co-dinero-rapido-dc.oss-us-west-1.aliyuncs.com/dino.json",
          options: Options(sendTimeout: const Duration(seconds: 5)));
      return response.data ?? [];
    } catch (e) {}
    return [];
  }
}
